﻿using Autofac;
using project.B12.IRepository.Base;
using project.B12.Repository.Base;
using System;
using System.IO;
using System.Reflection;

namespace project.B12.application.Ioc
{
    public class AutofacModuleRegister : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            var basePath = AppContext.BaseDirectory;

            #region 带有接口层的服务注入

            var servicesDllFile = Path.Combine(basePath, "project.B12.Service.dll");
            var repositoryDllFile = Path.Combine(basePath, "project.B12.Repository.dll");

            if (!(File.Exists(servicesDllFile) && File.Exists(repositoryDllFile)))
            {
                throw new Exception("dll错误，请检查。");
            }

            // 注册泛型仓储
            builder.RegisterGeneric(typeof(SugarRepository<>))
                .As(typeof(IBaseRepository<>))
                .InstancePerDependency();

            // 获取 Service.dll 程序集服务，并注册
            var assemblysServices = Assembly.LoadFrom(servicesDllFile);
            builder.RegisterAssemblyTypes(assemblysServices) // 程序集内所有具象类
                      .AsImplementedInterfaces() // 自动以其实现的所有接口类型暴露
                      .SingleInstance(); // 单例模式，每次调用，都会使用同一个实例化的对象；每次都用同一个对象

            // 获取 Repository.dll 程序集服务，并注册
            var assemblysRepository = Assembly.LoadFrom(repositoryDllFile);
            builder.RegisterAssemblyTypes(assemblysRepository)
                   .AsImplementedInterfaces()
                   //.InstancePerDependency(); // 默认模式，每次调用，都会重新实例化对象；每次请求都创建一个新的对象
                   .SingleInstance();

            #endregion 带有接口层的服务注入

            #region 没有接口层的服务层注入

            //因为没有接口层，所以不能实现解耦，只能用 Load 方法。
            //注意如果使用没有接口的服务，并想对其使用 AOP 拦截，就必须设置为虚方法
            //var assemblysServicesNoInterfaces = Assembly.Load("Blog.Core.Services");
            //builder.RegisterAssemblyTypes(assemblysServicesNoInterfaces);

            #endregion 没有接口层的服务层注入

            #region 没有接口的单独类，启用class代理拦截

            //只能注入该类中的虚方法，且必须是public
            //这里仅仅是一个单独类无接口测试，不用过多追问
            //builder.RegisterAssemblyTypes(Assembly.GetAssembly(typeof(Love)))
            //    .EnableClassInterceptors()
            //    .InterceptedBy(cacheType.ToArray());

            #endregion 没有接口的单独类，启用class代理拦截

            #region 单独注册一个含有接口的类，启用interface代理拦截

            //不用虚方法
            //builder.RegisterType<AopService>().As<IAopService>()
            //   .AsImplementedInterfaces()
            //   .EnableInterfaceInterceptors()
            //   .InterceptedBy(typeof(BlogCacheAOP));

            #endregion 单独注册一个含有接口的类，启用interface代理拦截
        }
    }
}